package memory;
import java.awt.event.*;

import javax.swing.Timer;

public class EventListener implements ActionListener {
	
	//Variables for card handling
	private Card[] cardsFlipped = new Card[2];
	private Card.State nextCardState = Card.State.DOLT;
	
	private CardPanel cardPanel;
	private PlayerPanel playerPanel;
	private Timer cardTimer = new Timer(2000,this);
	
	public EventListener(CardPanel c, PlayerPanel p) {
		
		cardPanel = c;
		playerPanel = p;
		
		//Configure timers
		cardTimer.setRepeats(false);
		
		//Bind listeners from buttons to this class
		connectListeners();
	
	}
	
	public void actionPerformed(ActionEvent e) {
		
		if( !checkTimers(e) ) {
			checkCards(e);
		}
		
	}
	
	private void connectListeners() {
		
		for(int i = 0 ; i < cardPanel.getNrOfCards() ; i++ ) {
			cardPanel.getCard(i).addActionListener(this);
		}
		
		
	}
	
	private boolean checkTimers(ActionEvent e) {
		
		
		if( e.getSource() == cardTimer) {
			
			
			//End of turn? change the state of both cards
			if( cardsFlipped[0] != null && cardsFlipped[1] != null ) {
								
				//The cards are a match
				if(nextCardState == Card.State.TAGET) {
					
					//Increase score
					Player currentPlayer = playerPanel.getCurrentPlayer();
					
					//Only one player in the game? if so don't increase score
					if(playerPanel.nrOfPlayers() != 1) 
						currentPlayer.incScore(1);
										
					//Disconnect listeners for the objects
					cardsFlipped[0].removeActionListener(this);
					cardsFlipped[1].removeActionListener(this);
					
				}
				else {
					
					//Only one player in the game? If so count the nr of tries and not pairs
					if(playerPanel.nrOfPlayers() == 1)
						playerPanel.getCurrentPlayer().incScore(1);
					
					//Next player.
					playerPanel.nextPlayer();
				}
				
				cardsFlipped[0].setStatus(nextCardState);
				cardsFlipped[1].setStatus(nextCardState);
				
				cardsFlipped[0] = null;
				cardsFlipped[1] = null;
				
				
				
				//Connect all cards again (except the ones that are out of the game
				for(int i = 0 ; i < cardPanel.getNrOfCards() ; i++ ) {
					if(cardPanel.getCard(i).getStatus() != Card.State.TAGET)
						cardPanel.getCard(i).addActionListener(this);
				}
				
				
			}
			//One card is flipped but the second wasn't pressed within time limit.
			else if( cardsFlipped[0] != null && cardsFlipped[1] == null ) {
				
				//Flip card back
				cardsFlipped[0].setStatus(Card.State.DOLT);
				cardsFlipped[0] = null;
				
				//Only one player in the game? If so count the nr of tries and not pairs
				if(playerPanel.nrOfPlayers() == 1)
					playerPanel.getCurrentPlayer().incScore(1);
				
				//Next player.
				playerPanel.nextPlayer();
				
			}
			
			return true;
		}
		
		return false;
	}
	
	//Check if the pressed button was one of the cards
	private void checkCards(ActionEvent e) {
	
		//Stop timer (this is to stop timer from possible go of and indicate
		//that the player didn't lift the card on time, when he in fact did.
		cardTimer.stop();
		
		//Since we've checked that it's not a timer we can be shure it's a card
		Card cardRef = (Card)e.getSource(); 		
					
		//Show it.
		cardRef.setStatus(Card.State.SYNLIGT);
				
		//Check if it's the second of two to be flipped
		if( cardsFlipped[0] != null ) {
					
			cardsFlipped[1] = cardRef;
			
			//Disconnect all cards until the next turn
			for(int i = 0 ; i < cardPanel.getNrOfCards() ; i++ ) {
				cardPanel.getCard(i).removeActionListener(this);
			}
			
			//Are the two cards alike?
			if( cardsFlipped[0].equals(cardsFlipped[1]) ) {
						
				nextCardState = Card.State.TAGET;
						
				//Start timer
				cardTimer.setInitialDelay(500);
				cardTimer.start();
				
						
			}
			//Two cards are flipped but there not equal
			else {											
				cardsFlipped[1] = cardRef;
						
				//Flip them back in 2s
				nextCardState = Card.State.DOLT;
				cardTimer.setInitialDelay(2000);
				cardTimer.start();			
						
			}
		}
		else {
					
			//This is the first of two to be flipped, save this card
			cardRef.removeActionListener(this);
			cardsFlipped[0] = cardRef;
			nextCardState = Card.State.DOLT;
					
			//Give player 10s to pick next card
			cardTimer.setInitialDelay(10000);
			cardTimer.start();
					
		}
				
	}

}
